/*
 * HTML5 Sortable jQuery Plugin
 * http://farhadi.ir/projects/html5sortable
 * 
 * Copyright 2012, Ali Farhadi
 * Released under the MIT license.
 */
(function($) {
var dragging, placeholders = $();
$.fn.sortable = function(options) {
    var method = String(options);
    options = $.extend({
        connectWith: false
    }, options);
    return this.each(function() {
        // 参数里有enable或disable或destroy
        if (/^enable|disable|destroy$/.test(method)) {
            // 有enable，设置后代元素的draggable属性为true，否则为false
            var items = $(this).children($(this).data('items')).attr('draggable', method == 'enable');
            // 有destroy属性，则是移除相关数据和事件
            if (method == 'destroy') {
                items.add(this).removeData('connectWith items')
                    .off('dragstart.h5s dragend.h5s selectstart.h5s dragover.h5s dragenter.h5s drop.h5s');
            }
            return;
        }
        // items是后代元素（依据参数的items属性来定）
        var isHandle, index, items = $(this).children(options.items);
        // placeholder是，<ul class="sortable-placeholder"></ul>，或<div class="sortable-placeholder"></div>
        var placeholder = $('<' + (/^ul|ol$/i.test(this.tagName) ? 'li' : 'div') + ' class="sortable-placeholder">');
        // 依据参数的handler属性,来绑定更后代元素的isHandle
        items.find(options.handle).mousedown(function() {
            isHandle = true;
        }).mouseup(function() {
            isHandle = false;
        });
        // 给元素的数据属性items赋值
        $(this).data('items', options.items);
        // placeholders放入placeholder
        placeholders = placeholders.add(placeholder);
        if (options.connectWith) {
            $(options.connectWith).add(this).data('connectWith', options.connectWith);
        }

        // 上面代码是做数据环境准备，下面代码开始绑定事件 


        items.attr('draggable', 'true').on('dragstart.h5s', function(e) {
            if (options.handle && !isHandle) {
                return false;
            }
            isHandle = false;
            // dataTransfer 是 拖拽元素的数据接口
            var dt = e.originalEvent.dataTransfer;
            // effectAllowed 拖拽效果
            dt.effectAllowed = 'move';
            // 为拖拽元素添加指定数据
            dt.setData('Text', 'dummy');
            // dragging是正在拖拽的元素，index是该元素所在数组的位置
            index = (dragging = $(this)).addClass('sortable-dragging').index();
        }).on('dragend.h5s', function() {
            dragging.removeClass('sortable-dragging').show();
            // 移除 placeholders，但保留事件
            placeholders.detach();
            if (index != dragging.index()) {
                items.parent().trigger('sortupdate', {item: dragging});
            }
            // 释放引用
            dragging = null;
        }).not('a[href], img').on('selectstart.h5s', function() {
            // 当元素选中时，阻止元素背景色边蓝
            this.dragDrop && this.dragDrop();
            return false;
        }).end().add([this, placeholder]).on('dragover.h5s dragenter.h5s drop.h5s', function(e) {
            // 注意dragenter，dragover，drop的this是目标元素

            // 拖拽元素，不是items集合内，不给拖拽
            if (!items.is(dragging) && options.connectWith !== $(dragging).parent().data('connectWith')) {
                return true;
            }
            if (e.type == 'drop') {
                e.stopPropagation();
                // 当拖拽的对象，被放下。则在坑后面填入多拽的对象
                placeholders.filter(':visible').after(dragging);
                return false;
            }
            e.preventDefault();
            e.originalEvent.dataTransfer.dropEffect = 'move';
            if (items.is(this)) {

                if (options.forcePlaceholderSize) {
                    // 大多数情况下，这一步不会实现
                    placeholder.height(dragging.outerHeight());
                }
                // 隐藏被拖动的元素
                dragging.hide();
                $(this)[placeholder.index() < $(this).index() ? 'after' : 'before'](placeholder);
                placeholders.not(placeholder).detach();
                console.log(this);

            } else if (!placeholders.is(this) && !$(this).children(options.items).length) {
                placeholders.detach();
                $(this).append(placeholder);
            }
            return false;
        });
    });
};
})(jQuery);